#
# P4Dialogs.py
#
# Dialogs used in the SNiFF+ 3.x Perforce Adapter
#
# Author: Martin Oberhuber
# Copyright (c) 1998, 1999 TakeFive Software, Salzburg
#
# History:
#	1999-05-03  MOB  Created
#

# Standard Modules
import string, time
from vcs import SYSTEM, WINDOWS, UNIX, NL, TRUE, FALSE

# Modules required for the Dialogs
import os
from etgui import *
from etguiimpl import PotGuiPopupButton
from PageLayout import *
#import CmdNo
#import ListEditor
import P4Prefs

#----------Constants-----------------------------------------------------
ModMark = "(P4Dialogs) "

#----------Helper functions----------------------------------------------

#----------Dialogs----------------------------------------------------------

def MakeP4FormLayout(model, FieldList, BigFields, DisabledFields):
	dialogItems=[]
	for curField in FieldList:
		dialogItems.append(curField+":")
		if curField in BigFields:
			tv=PotGuiTextView(curField, TextView(), Point(400,100))
		else:
			tv=PotTextField(curField)
		dialogItems.append(tv)
		if curField in DisabledFields:
			tv.Disable()
	return MakeSectionLayout(Form(items=dialogItems))

def MakeP4SimpleLayout(model, FieldList, BigFields, DisabledFields):
	dialogItems=[]
	for curField in FieldList:
		if curField in BigFields:
			tv=PotGuiTextView(curField, TextView(), Point(640,100))
			dialogItems.append(TextItem(curField+":"))
			dialogItems.append(tv)
		else:
			if curField in DisabledFields:
				tv=TextItem(model.GetValue(curField))
			else:
				tv=PotTextField(curField, width = 40)
			dialogItems.append(
				HBox(items=[
						TextItem(curField+":"+" "*(18-len(curField))),
						tv,
					]
				)
			)
	return MakeSectionLayout(VBox(items=dialogItems, gap=gPoint3))

def MakeP4AlignedLayout(model, FieldList, BigFields, DisabledFields):
	dialogItems=[]
	for curField in FieldList:
		if curField in BigFields:
			tv=PotGuiTextView(curField, TextView(), Point(400,60))
			dialogItems.append(TextItem(curField+":"))
			dialogItems.append(tv)
		else:
			tv=PotTextField(curField, width = 40)
			dialogItems.append(
				AlignBox(
					eVObjHRight,
					flags=eVObjVFixed,
					inner=HBox(
						items=[
							TextItem(curField+":"),
							Filler(gPointBorderGap, flags=eVObjHGapExpand),
							tv,
						]
					)
				)
			)
		if curField in DisabledFields:
			# print "Disabling ",curField
			tv.Disable()
	return MakeSectionLayout(VBox(items=dialogItems, gap=gPoint3))

def P4ModelFromForm(P4Form):
	"""Create a PotGuiModel and a FieldList from the P4Form supplied
	returns a triple of (model, FieldList, BigFields)"""
	marker = ModMark + "P4ModelFromForm "
	model = PotGuiModel()
	curField = ""
	curValue = ""
	FieldList = []
	BigFields = []
	#for curLine in string.split(P4Form, NL):
	for curLine in P4Form:
		if len(curLine) == 0:
			# Empty lines just split fields.
			model.SetValue(curField, curValue)
			curField = ""
			curValue = ""
			continue
		elif curLine[0] == "#": 
			# Comment: here, we could extract Help information for ToolTips.
			continue
		elif curLine[0] == "\t":
			# append text into previous field
			if not curField:
				print marker, "Error: No fieldname for line <",curLine,">"
				continue
			if curValue:
				curValue = curValue + NL + curLine[1:]
			else:
				# this is a "big" field!
				BigFields.append(curField)
				curValue = curLine[1:]
		else:
			# A new field name
			theTab = string.find(curLine, ":")
			if (theTab <= 0):
				print marker, "Error: illegal line <",curLine,">"
				continue
			curField = curLine[:theTab]
			FieldList.append(curField)
			curValue = curLine[theTab+2:]
	# there is usually no empty line after the last field!
	if curField:
		model.SetValue(curField, curValue)
	return (model, FieldList, BigFields)

def P4FormFromModel(model, FieldList, BigFields):
	"""Make a Perforce Form from the Model"""
	theResult = ""
	for curField in FieldList:
		if curField in BigFields:
			theResult = theResult + curField + ":" + NL
			for curLine in string.split(model.GetValue(curField),NL):
				theResult = theResult + "\t" + curLine + NL
		else:
			theResult = theResult + curField + ":\t" + model.GetValue(curField) + NL
		theResult = theResult + NL
	return theResult

def P4ShowDialog(DialogTitle, model, FieldList, BigFields, DisabledFields=[]):
	#theView = MakeP4FormLayout(model, FieldList, BigFields, DisabledFields)
	theView = MakeP4SimpleLayout(model, FieldList, BigFields, DisabledFields)
	#theView = MakeP4AlignedLayout(model, FieldList, BigFields, DisabledFields)
	return ShowSubDialog(DialogTitle, model, theView)

def P4GenDialog(DialogTitle, P4Form, DisabledFields=[]):
	"""Create a SNiFF+ Dialog from the Text form output by Perforce -o Commands.
	EnableFields has a list of field names to be disabled."""
	marker = ModMark + "P4GenDialog "
	(model, FieldList, BigFields) = P4ModelFromForm(P4Form)
	retval = P4ShowDialog(DialogTitle, model, FieldList, BigFields, DisabledFields)
	if not retval:
		return ""
	# Now, create the Perforce text of the User's Entries
	return P4FormFromModel(model, FieldList, BigFields)

_ErrorDialogTimestamp=0
_ErrorDialogLastText=""
def ErrorDialog(Text, Title="Error", allowRepeat=1):
	global _ErrorDialogTimestamp, _ErrorDialogLastText
	curTime = time.time()
	diffTime = curTime - _ErrorDialogTimestamp
	if allowRepeat and _ErrorDialogLastText == Text and diffTime < P4Prefs.ErrorDialogTimeout:
		# if the same dialog was displayed less than 0.3 sec before, don't show again
		_ErrorDialogTimestamp = curTime
		return 1
	model = PotGuiModel()
	inner= Matte(
		gPointBorderGap,
		VExpander(
			items= (
				Filler(Point(0,10)),
				MultilineTextItem(Text),
				Filler(Point(0,15)),
				AlignBox(
					#eVObjHRight,
					eVObjHCenter,
					flags=eVObjVFixed,
					inner=HBox(
						align=eVObjVBase|eVObjHEqual,
						items=[
							ActionButton(CmdNo.cIdOk,"OK",default=1)
						]
					)
				)
			)
		)
	)
	dialog=PotGuiDialog(
		model,
		inner,
		Title,
	eWinBlock
	)
	retval = dialog.ShowUnderMouse()
	_ErrorDialogLastText = Text
	_ErrorDialogTimestamp = time.time()
	return retval

def ChoiceDialog(Title, Text="", choiceList=[], defaultChoice=""):
	"""Display a dialog with a description which may be broken on spaces,
	and a single choicebox to choose from a list"""
	if not choiceList: choiceList=[defaultChoice]
	if not defaultChoice in choiceList: defaultChoice=choiceList[0]
	model = PotGuiModel()
	choiceBox = PotGuiPopupButton("theChoice")
	for curChoice in choiceList:
		choiceBox.AddItem(curChoice,curChoice)
	model.SetValue("theChoice", defaultChoice)
	inner= Matte(
		gPointBorderGap,
		VExpander(
			items= (
				Filler(Point(0,10)),
				MultilineTextItem(Text),
				Filler(Point(0,15)),
				AlignBox(
					#eVObjHRight,
					eVObjHCenter,
					flags=eVObjVFixed,
					inner=HBox(
						align=eVObjVBase|eVObjHEqual,
						items=[
							choiceBox
						]
					)
				),
				Filler(Point(0,15)),
				AlignBox(
					#eVObjHRight,
					eVObjHCenter,
					flags=eVObjVFixed,
					inner=HBox(
						align=eVObjVBase|eVObjHEqual,
						items=[
							ActionButton(CmdNo.cIdOk,"OK",default=1),
							ActionButton(CmdNo.cIdCancel,"Cancel")
						]
					)
				)
			)
		)
	)
	dialog=PotGuiDialog(
		model,
		inner,
		Title,
	eWinBlock
	)
	retval = dialog.ShowUnderMouse()
	if retval == CmdNo.cIdOk:
		return model.GetValue("theChoice")
	else:
		return ""

def AskQuestionDialog(Header, Description="", defaultText="", bigEditor=0):
	"""Edit the contents of File in a modal Dialog with OK Button"""
	model = PotGuiModel()
	model.SetValue("Text", defaultText)
	if bigEditor:
		tv = PotGuiTextView("Text", TextView(), Point(600,300))
	else:
		tv = PotTextField("Text")
	rc=ShowSubDialog(Header,
		model,
		MakeSectionLayout(
			TextItem(str(Description)),
			tv
		)
	)
	if not rc: return None
	return model.GetValue("Text")

def askYesNo(title, text):
	from etgui import ShowDialog
	from YesNoDialog import YesNoDialog
	dlg = YesNoDialog(title, text)
	ShowDialog(dlg)
	return dlg.Answer()

#----------Tests----------------------------------------------------------

def TestClientDialog():
	retval = P4GenDialog("P4 Client", string.split("""#
# A Perforce Client Specification.
#
#  Client:      The client name.
#  Owner:       The user who created this client.
#  Update:      The date this specification was last modified.
#  Access:      The date this client was last used in any way.
#  Description: A short description of the client (optional).
#  Root:        The base directory of the client workspace.
#  Options:     Client options:
#                      [no]allwrite [no]clobber [no]compress
#                      [no]crlf [un]locked [no]modtime
#  View:        Lines to map depot files into the client workspace.
#
# Use 'p4 help client' to see more about client views and options.

Client:	mober-londo

Owner:	mober

Description:
	Created by mober.

Root:	//D/WS/P4Adapter/SNIFF_DIR

Options:	noallwrite noclobber nocompress crlf unlocked nomodtime

View:
	//depot/... //mober-londo/...""",NL), ["Client"] )
	print retval

if __name__ == '__main__':
	#TestClientDialog()
	rv=ChoiceDialog("Test Choice", "Test Text", ["Choice 1", "Choice 2"])
	print rv

